package Window;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Decorations;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import Builder.BrickSelectionManager;
import Command.LDrawPart;
import Command.PartTypeT;
import Grouping.GroupingManager;
import LDraw.Files.LDrawMPDModel;
import LDraw.Files.LDrawStep;
import LDraw.Support.LDrawDirective;
import LDraw.Support.PartCache;
import Notification.ILDrawSubscriber;
import Notification.INotificationMessage;
import Notification.LDrawDirectiveAdded;
import Notification.LDrawDirectiveModified;
import Notification.LDrawDirectiveRemoved;
import Notification.NotificationCenter;
import Notification.NotificationMessageT;
import Resource.ResourceManager;
import UndoRedo.ChangeDirectivesIndexAction;
import UndoRedo.ChangeDirectivesParentStepAction;
import UndoRedo.ChangeStepIndexAction;
import UndoRedo.DirectiveAction;
import UndoRedo.LDrawUndoRedoManager;
public class GroupEditorView implements ILDrawSubscriber, Runnable, Listener {
private Tree groupTreeComponent = null;
private TreeEditor editor;
private MOCBuilder mocBuilder = null;
private boolean isDraging;
private HashMap<NotificationMessageT, Boolean> flags;
private HashMap<NotificationMessageT, ArrayList<INotificationMessage>> messageListMap;
private boolean isTerminate = false;
private Lock mutexForMessageListMap;
private Image isExistImage;
private Image connectivityImage;
private Image noConnectivityImage;
private Image folderImage;
public GroupEditorView(MOCBuilder builder) {
mutexForMessageListMap = new ReentrantLock(true);
this.mocBuilder = builder;
flags = new HashMap<NotificationMessageT, Boolean>();
messageListMap = new HashMap<NotificationMessageT, ArrayList<INotificationMessage>>();
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawDirectiveDidChange);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawPartAdded);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawPartRemoved);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawStepRemoved);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawStepAdded);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawPartSelected);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawPartTransformed);
NotificationCenter.getInstance().addSubscriber(this,
NotificationMessageT.LDrawFileActiveModelDidChanged);
flags.put(NotificationMessageT.LDrawDirectiveDidChange, false);
flags.put(NotificationMessageT.LDrawPartAdded, false);
flags.put(NotificationMessageT.LDrawPartRemoved, false);
flags.put(NotificationMessageT.LDrawPartSelected, false);
flags.put(NotificationMessageT.LDrawFileActiveModelDidChanged, false);
flags.put(NotificationMessageT.LDrawStepAdded, false);
flags.put(NotificationMessageT.LDrawStepRemoved, false);
flags.put(NotificationMessageT.LDrawPartTransformed, false);
messageListMap.put(NotificationMessageT.LDrawDirectiveDidChange,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawPartAdded,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawPartRemoved,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawPartSelected,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawFileActiveModelDidChanged,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawStepRemoved,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawStepAdded,
new ArrayList<INotificationMessage>());
messageListMap.put(NotificationMessageT.LDrawPartTransformed,
new ArrayList<INotificationMessage>());
initTree();
startUpdateViewThread();
}
public void terminate() {
this.isTerminate = true;
}
private void startUpdateViewThread() {
new Thread(this).start();
}
protected ArrayList<INotificationMessage> getMessageList(
NotificationMessageT messageType) {
ArrayList<INotificationMessage> copy = new ArrayList<INotificationMessage>();
mutexForMessageListMap.lock();
ArrayList<INotificationMessage> original = messageListMap
.get(messageType);
copy.addAll(original);
original.clear();
mutexForMessageListMap.unlock();
return copy;
}
protected void updateStep(final LDrawStep step) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (mocBuilder != null) {
int index = 0;
TreeItem treeItem_Step = null;
groupTreeComponent.setVisible(false);
groupTreeComponent.setRedraw(false);
String stepName;
for (LDrawDirective directive : mocBuilder
.getWorkingLDrawFile().activeModel()
.subdirectives()) {
if (LDrawStep.class.isInstance(directive)) {
if (index < groupTreeComponent.getItemCount()) {
treeItem_Step = groupTreeComponent
.getItem(index);
if (treeItem_Step.getData() != directive)
treeItem_Step.setData(directive);
} else {
treeItem_Step = new TreeItem(
groupTreeComponent, SWT.NONE);
stepName = ((LDrawStep) directive)
.getStepName();
if (stepName == null || "".equals(stepName)) {
treeItem_Step
.setText(((LDrawStep) directive)
.browsingDescription());
} else {
treeItem_Step.setText(stepName);
}
treeItem_Step.setData(directive);
}
if (mocBuilder.getCurrentStep() == directive) {
setBold(treeItem_Step);
}
index++;
}
}
for (; index < groupTreeComponent.getItemCount(); index++) {
groupTreeComponent.getItem(index).dispose();
}
treeItem_Step = null;
for (TreeItem item : groupTreeComponent.getItems())
if (item.getData() == step) {
treeItem_Step = item;
break;
}
if (treeItem_Step == null) {
groupTreeComponent.setRedraw(true);
groupTreeComponent.setVisible(true);
return;
}
if (mocBuilder.getCurrentStep() == step)
setBold(treeItem_Step);
treeItem_Step.removeAll();
ArrayList<LDrawDirective> directives = step.subdirectives();
TreeItem treeItem = null;
for (LDrawDirective directive : directives) {
if (LDrawPart.class.isInstance(directive) == false)
continue;
treeItem = new TreeItem(treeItem_Step, SWT.NONE);
String description = PartCache.getInstance()
.getPartName(
((LDrawPart) directive).displayName());
if (description == null)
description = ((LDrawPart) directive).displayName();
else
description = ((LDrawPart) directive).displayName()
+ " : " + description;
treeItem.setText(description
+ " "
+ ((LDrawPart) directive).getLDrawColor()
.getColorCode());
treeItem.setData(directive);
LDrawPart part = (LDrawPart) directive;
if (part.isPartDataExist() == false)
treeItem.setImage(isExistImage);
else if (part.isConnectivityInfoExist()) {
treeItem.setImage(connectivityImage);
} else {
treeItem.setImage(noConnectivityImage);
}
}
treeItem_Step.setExpanded(true);
groupTreeComponent.setRedraw(true);
groupTreeComponent.setVisible(true);
}
}
});
}
private void initTree() {
if (mocBuilder != null) {
new Thread(new Runnable() {
public void run() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (!groupTreeComponent.isDisposed()) {
groupTreeComponent.setVisible(false);
groupTreeComponent.removeAll();
int index = 0;
for (LDrawDirective directive : mocBuilder
.getWorkingLDrawFile().activeModel()
.subdirectives()) {
if (LDrawStep.class.isInstance(directive)) {
index++;
drawStep(index, (LDrawStep) directive);
}
}
setSelection();
groupTreeComponent.setVisible(true);
}
}
});
}
}).start();
}
}
private void drawStep(int index, LDrawStep step) {
TreeItem treeItem_Step = new TreeItem(groupTreeComponent, SWT.NONE);
String stepName = step.getStepName();
if (stepName == null || "".equals(stepName)) {
treeItem_Step.setText("Step " + index);
} else {
treeItem_Step.setText(stepName);
}
treeItem_Step.setData(step);
treeItem_Step.setImage(folderImage);
if (mocBuilder.getCurrentStep() == step) {
setBold(treeItem_Step);
}
TreeItem treeItem;
groupTreeComponent.setRedraw(false);
for (LDrawDirective directive : step.subdirectives()) {
if (LDrawPart.class.isInstance(directive)) {
LDrawPart part = (LDrawPart) directive;
treeItem = new TreeItem(treeItem_Step, SWT.NONE);
String description = PartCache.getInstance().getPartName(
((LDrawPart) directive).displayName());
if (description == null)
description = ((LDrawPart) directive).displayName();
else
description = ((LDrawPart) directive).displayName() + " : "
+ description;
treeItem.setText(description
+ " "
+ ((LDrawPart) directive).getLDrawColor()
.getColorCode());
treeItem.setData(part);
if (part.isPartDataExist() == false)
treeItem.setImage(isExistImage);
else if (part.isConnectivityInfoExist())
treeItem.setImage(connectivityImage);
else {
treeItem.setImage(noConnectivityImage);
}
}
}
treeItem_Step.setExpanded(true);
groupTreeComponent.setRedraw(true);
}
private void setBold(TreeItem selectedItem) {
Display display = groupTreeComponent.getDisplay();
if (groupTreeComponent.getFont() == null)
return;
FontData datas[] = groupTreeComponent.getFont().getFontData();
for (FontData data : datas) {
data.setStyle(SWT.NORMAL);
}
Font normalFont = new Font(display, datas);
for (FontData data : datas) {
data.setStyle(SWT.BOLD);
}
Font boldFont = new Font(display, datas);
for (TreeItem item : groupTreeComponent.getItems()) {
if (item.equals(selectedItem)) {
item.setFont(boldFont);
} else {
item.setFont(normalFont);
}
}
}
@Override
public void receiveNotification(NotificationMessageT messageType,
INotificationMessage msg) {
flags.put(messageType, true);
if (msg != null) {
mutexForMessageListMap.lock();
messageListMap.get(messageType).add(msg);
mutexForMessageListMap.unlock();
}
}
public void generateView(final Composite parent) {
Display display = parent.getDisplay();
GridLayout layout = new GridLayout();
layout.marginTop = -5;
layout.marginLeft = -5;
layout.marginRight = -5;
layout.marginBottom = -5;
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Label label = new Label(composite, SWT.NONE);
label.setText("Groups");
groupTreeComponent = new Tree(composite, SWT.MULTI | SWT.BORDER);
groupTreeComponent.setLayout(new GridLayout());
groupTreeComponent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
true));
groupTreeComponent.setMenu(createPopupMenu(parent.getShell()));
isExistImage = ResourceManager.getInstance().getImage(display,
"/Resource/Image/not_exist.png");
connectivityImage = ResourceManager.getInstance().getImage(display,
"/Resource/Image/chain.png");
noConnectivityImage = ResourceManager.getInstance().getImage(display,
"/Resource/Image/chain_exclamation.png");
folderImage = ResourceManager.getInstance().getImage(display,
"/Resource/Image/folder_brick.png");
groupTreeComponent.addMouseListener(new MouseListener() {
@Override
public void mouseUp(MouseEvent e) {
}
@Override
public void mouseDown(MouseEvent e) {
TreeItem item = groupTreeComponent.getItem(new Point(e.x, e.y));
if (item == null) {
BrickSelectionManager.getInstance().clearSelection();
groupTreeComponent.setSelection(new TreeItem[0]);
}
}
@Override
public void mouseDoubleClick(MouseEvent e) {
TreeItem[] selectedItems = groupTreeComponent.getSelection();
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawStep) {
BrickSelectionManager.getInstance().clearSelection();
LDrawStep step = (LDrawStep) object;
for (LDrawDirective subDirective : step.subdirectives()) {
if (subDirective instanceof LDrawPart) {
LDrawPart part = (LDrawPart) subDirective;
BrickSelectionManager.getInstance()
.addPartToSelection(part);
}
}
}
GlobalFocusManager.getInstance().forceFocusToMainView();
}
}
});
groupTreeComponent.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent event) {
TreeItem[] selectedItems = groupTreeComponent.getSelection();
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawStep) {
setBold(selectedItems[0]);
mocBuilder.setCurrentStep((LDrawStep) object);
return;
}
}
BrickSelectionManager.getInstance().clearSelection();
LDrawDirective directive = null;
for (TreeItem selectedItem : selectedItems) {
directive = (LDrawDirective) selectedItem.getData();
if (directive instanceof LDrawStep) {
LDrawStep step = (LDrawStep) directive;
for (LDrawDirective subDirective : step.subdirectives()) {
if (subDirective instanceof LDrawPart) {
LDrawPart part = (LDrawPart) subDirective;
BrickSelectionManager.getInstance()
.addPartToSelection(part);
}
}
} else if (directive instanceof LDrawPart) {
LDrawPart part = (LDrawPart) directive;
if (BrickSelectionManager.getInstance()
.containsInSelection(part)) {
continue;
}
BrickSelectionManager.getInstance().addPartToSelection(
part);
// GlobalConnectivityManager.getInstance()
// .updateMatrix(part);
}
}
if (selectedItems.length == 1) {
LDrawPart part = (LDrawPart) directive;
mocBuilder.getBrickMovementGuideRenderer().setLDrawPart(
part);
MOCBuilder.getInstance().getCamera()
.moveTo(part.position());
}
// GlobalConnectivityManager_0622.getInstance().updateMatrixAll();
}
@Override
public void widgetDefaultSelected(SelectionEvent arg0) {
}
});
groupTreeComponent.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent arg0) {
switch (arg0.keyCode) {
case SWT.DEL:
deleteSelectedItems();
break;
case SWT.F5:
initTree();
break;
case SWT.F2:
if (groupTreeComponent.getSelectionCount() == 1)
renameStep();
break;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
}
});
groupTreeComponent.addKeyListener(new BuilderEventHandler(mocBuilder));
setDragAndDrop();
editor = new TreeEditor(groupTreeComponent);
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
editor.minimumWidth = 50;
}
private Menu createPopupMenu(Decorations parent) {
Menu menu = new Menu(parent, SWT.POP_UP);
MenuItem addStepItem = new MenuItem(menu, SWT.PUSH);
addStepItem.setText("New Group");
addStepItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
TreeItem[] selectedItems = groupTreeComponent.getSelection();
DirectiveAction action = new DirectiveAction();
LDrawStep step;
if (selectedItems.length == 1) {
Object object = selectedItems[0].getData();
if (object instanceof LDrawStep) {
LDrawMPDModel model = mocBuilder.getWorkingLDrawFile()
.activeModel();
step = mocBuilder.addStepToWorkingFileAt(model
.indexOfDirective((LDrawStep) object));
} else {
step = mocBuilder.addStepToWorkingFile();
}
} else {
step = mocBuilder.addStepToWorkingFile();
}
action.addDirective(step);
LDrawUndoRedoManager.getInstance().pushUndoAction(action);
GlobalFocusManager.getInstance().forceFocusToMainView();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
final MenuItem renameItem = new MenuItem(menu, SWT.PUSH);
renameItem.setText("Rename Group");
renameItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
renameStep();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
new MenuItem(menu, SWT.SEPARATOR);
final MenuItem deleteItem = new MenuItem(menu, SWT.PUSH);
deleteItem.setText("Delete");
deleteItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
deleteSelectedItems();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
new MenuItem(menu, SWT.SEPARATOR);
MenuItem hideStep = new MenuItem(menu, SWT.PUSH);
hideStep.setText("Hide");
hideStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleHide();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
MenuItem showStep = new MenuItem(menu, SWT.PUSH);
showStep.setText("Show");
showStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleShow();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
MenuItem hideAllStep = new MenuItem(menu, SWT.PUSH);
hideAllStep.setText("Hide All");
hideAllStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleHideAll();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
MenuItem showAllStep = new MenuItem(menu, SWT.PUSH);
showAllStep.setText("Show All");
showAllStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleShowAll();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
new MenuItem(menu, SWT.SEPARATOR);
final MenuItem makeGroupItem = new MenuItem(menu, SWT.PUSH);
makeGroupItem.setText("Group Selected Parts");
makeGroupItem.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
mocBuilder.makeNewStepFromSeletion();
GlobalFocusManager.getInstance().forceFocusToMainView();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
final MenuItem seprateStep = new MenuItem(menu, SWT.PUSH);
seprateStep.setText("Separate Into Subgroups based on Connection");
seprateStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleSeparateStep();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
MenuItem mergeStep = new MenuItem(menu, SWT.PUSH);
mergeStep.setText("Put All Into a Single Group");
mergeStep.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleMergeStep();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
new MenuItem(menu, SWT.SEPARATOR);
final MenuItem makeModel = new MenuItem(menu, SWT.PUSH);
makeModel.setText("Make Selected Parts Into a Submodel");
makeModel.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleMakeASubmodel();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
makeModel.setEnabled(false);
final MenuItem extractModel = new MenuItem(menu, SWT.PUSH);
extractModel.setText("Extract Parts From a Submodel");
extractModel.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
handleExtractPartsFromASubmodel();
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
menu.addMenuListener(new MenuListener() {
@Override
public void menuShown(MenuEvent e) {
int count = groupTreeComponent.getSelectionCount();
if (count > 1) {
seprateStep.setEnabled(true);
deleteItem.setEnabled(true);
makeModel.setEnabled(true);
extractModel.setEnabled(false);
LDrawDirective directive;
for (TreeItem item : groupTreeComponent.getSelection()) {
directive = (LDrawDirective) item.getData();
if (directive instanceof LDrawStep) {
makeGroupItem.setEnabled(false);
return;
}
}
makeGroupItem.setEnabled(true);
renameItem.setEnabled(false);
} else if (count == 1) {
makeModel.setEnabled(true);
extractModel.setEnabled(false);
if (groupTreeComponent.getSelection()[0].getData() instanceof LDrawPart) {
if (((LDrawPart) groupTreeComponent.getSelection()[0]
.getData()).getCacheType() == PartTypeT.PartTypeSubmodel)
extractModel.setEnabled(true);
}
seprateStep.setEnabled(true);
deleteItem.setEnabled(true);
makeGroupItem.setEnabled(false);
if (groupTreeComponent.getSelection()[0].getData() instanceof LDrawStep)
renameItem.setEnabled(true);
else
renameItem.setEnabled(false);
} else {
makeModel.setEnabled(false);
extractModel.setEnabled(false);
seprateStep.setEnabled(false);
deleteItem.setEnabled(false);
makeGroupItem.setEnabled(false);
renameItem.setEnabled(false);
}
}
@Override
public void menuHidden(MenuEvent e) {
}
});
return menu;
}
protected void handleMakeASubmodel() {
for (final TreeItem item : groupTreeComponent.getSelection()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
for (LDrawDirective directive : step.subdirectives()) {
if (directive instanceof LDrawPart) {
BrickSelectionManager.getInstance().addPartToSelection(
(LDrawPart) directive);
}
}
} else if (item.getData() instanceof LDrawPart) {
LDrawPart part = (LDrawPart) item.getData();
BrickSelectionManager.getInstance().addPartToSelection(part);
}
}
mocBuilder.makeASubmodelFromSelection();
}
protected void handleMergeStep() {
GroupingManager.getInstance().mergeAll();
}
protected void handleSeparateStep() {
for (final TreeItem item : groupTreeComponent.getSelection()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
GroupingManager.getInstance().doGrouping(step);
}
}
}
protected void handleExtractPartsFromASubmodel() {
if (groupTreeComponent.getSelection().length != 1)
return;
TreeItem item = groupTreeComponent.getSelection()[0];
LDrawPart part = (LDrawPart) item.getData();
mocBuilder.extractPartsFromASubmodel(part);
}
protected void handleShowAll() {
for (final TreeItem item : groupTreeComponent.getItems()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
for (LDrawDirective directive : step.subdirectives())
if (directive instanceof LDrawPart)
((LDrawPart) directive).setHidden(false);
}
}
NotificationCenter.getInstance().postNotification(
NotificationMessageT.NeedReDraw);
}
protected void handleHideAll() {
for (final TreeItem item : groupTreeComponent.getItems()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
for (LDrawDirective directive : step.subdirectives())
if (directive instanceof LDrawPart)
((LDrawPart) directive).setHidden(true);
}
}
NotificationCenter.getInstance().postNotification(
NotificationMessageT.NeedReDraw);
}
protected void handleHide() {
for (final TreeItem item : groupTreeComponent.getSelection()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
for (LDrawDirective directive : step.subdirectives())
if (directive instanceof LDrawPart)
((LDrawPart) directive).setHidden(true);
}else if (item.getData() instanceof LDrawPart) {
((LDrawPart) item.getData()).setHidden(true);
}
}
NotificationCenter.getInstance().postNotification(
NotificationMessageT.NeedReDraw);
}
protected void handleShow() {
for (final TreeItem item : groupTreeComponent.getSelection()) {
if (item.getData() instanceof LDrawStep) {
LDrawStep step = (LDrawStep) item.getData();
for (LDrawDirective directive : step.subdirectives())
if (directive instanceof LDrawPart)
((LDrawPart) directive).setHidden(false);
}else if (item.getData() instanceof LDrawPart) {
((LDrawPart) item.getData()).setHidden(true);
}
}
NotificationCenter.getInstance().postNotification(
NotificationMessageT.NeedReDraw);
}
void setDragAndDrop() {
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
int operations = DND.DROP_MOVE;
DragSource source = new DragSource(groupTreeComponent, operations);
source.setTransfer(types);
source.addDragListener(new DragSourceListener() {
@Override
public void dragStart(DragSourceEvent event) {
if (groupTreeComponent.getSelectionCount() == 0) {
event.doit = false;
} else {
isDraging = true;
event.image = null;
}
}
@Override
public void dragSetData(DragSourceEvent event) {
event.data = "DRAG";
}
@Override
public void dragFinished(DragSourceEvent event) {
if (isDraging) {
isDraging = false;
initTree();
}
}
});
DropTarget target = new DropTarget(groupTreeComponent, operations);
target.setTransfer(types);
target.addDropListener(new DropTargetListener() {
@Override
public void dropAccept(DropTargetEvent event) {
}
@Override
public void drop(DropTargetEvent event) {
if (event.data == null
|| groupTreeComponent.getSelectionCount() == 0) {
event.detail = DND.DROP_NONE;
isDraging = false;
return;
}
TreeItem[] selectedItems = groupTreeComponent.getSelection();
Object data;
LDrawDirective targetDirective = null;
LDrawStep targetStep = null;
boolean targetIsStep = false;
if (event.item != null) {
if (event.item.equals(selectedItems[0])) {
event.detail = DND.DROP_NONE;
isDraging = false;
return;
}
data = event.item.getData();
if (data instanceof LDrawStep) {
targetStep = (LDrawStep) data;
targetIsStep = true;
} else if (data instanceof LDrawDirective) {
targetDirective = (LDrawDirective) data;
targetStep = targetDirective.enclosingStep();
} else
return;
} else
return;
mocBuilder.setCurrentStep(targetStep);
data = selectedItems[0].getData();
LDrawDirective srcDirective = null;
LDrawStep srcStep = null;
boolean srcIsStep = false;
boolean srcDirectiveHasSameStep = true;
if (data instanceof LDrawStep) {
srcStep = (LDrawStep) data;
srcIsStep = true;
}
if (srcIsStep) {
LDrawMPDModel model = mocBuilder.getWorkingLDrawFile()
.activeModel();
int newIndex = model.indexOfDirective(targetStep);
int oldIndex = model.indexOfDirective(srcStep);
mocBuilder.changeStepIndex(srcStep, newIndex);
mocBuilder.setCurrentStep(srcStep);
LDrawUndoRedoManager.getInstance().pushUndoAction(
new ChangeStepIndexAction(mocBuilder, srcStep,
oldIndex, newIndex));
GlobalFocusManager.getInstance().forceFocusToMainView();
} else {
LDrawStep tempStep = null;
for (int i = 0; i < selectedItems.length; i++) {
srcDirective = (LDrawDirective) (selectedItems[i]
.getData());
tempStep = srcDirective.enclosingStep();
if (srcStep != null && srcStep != tempStep) {
srcDirectiveHasSameStep = false;
break;
}
srcStep = tempStep;
}
if (srcDirectiveHasSameStep && srcStep == targetStep) {
ChangeDirectivesIndexAction action = new ChangeDirectivesIndexAction();
int newIndex;
int oldIndex;
for (int i = 0; i < selectedItems.length; i++) {
srcDirective = (LDrawDirective) selectedItems[i]
.getData();
if (targetIsStep)
newIndex = i;
else
newIndex = targetStep
.indexOfDirective(targetDirective)
+ i
+ 1;
oldIndex = srcStep.indexOfDirective(srcDirective);
action.add(mocBuilder, srcStep, srcDirective,
oldIndex, newIndex);
mocBuilder.changeDirectiveIndex(srcStep,
srcDirective, newIndex);
}
LDrawUndoRedoManager.getInstance().pushUndoAction(
action);
GlobalFocusManager.getInstance().forceFocusToMainView();
BrickSelectionManager.getInstance().clearSelection(
false);
} else {
ChangeDirectivesParentStepAction action = new ChangeDirectivesParentStepAction();
int oldIndex;
for (int i = 0; i < selectedItems.length; i++) {
srcDirective = (LDrawDirective) selectedItems[i]
.getData();
srcStep = (LDrawStep) (srcDirective
.enclosingDirective());
oldIndex = srcStep.indexOfDirective(srcDirective);
action.add(mocBuilder, targetStep, srcDirective,
oldIndex);
mocBuilder.ChangeDirectivesParentStepAction(
srcDirective, srcStep, targetStep);
}
LDrawUndoRedoManager.getInstance().pushUndoAction(
action);
GlobalFocusManager.getInstance().forceFocusToMainView();
BrickSelectionManager.getInstance().clearSelection(
false);
}
}
}
@Override
public void dragOver(DropTargetEvent event) {
if (isDraging) {
event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
if (event.item != null) {
TreeItem item = (TreeItem) event.item;
Object data = item.getData();
if (groupTreeComponent.getSelection().length == 0)
return;
Object selectedData = groupTreeComponent.getSelection()[0]
.getData();
if (data.equals(selectedData)
|| (selectedData instanceof LDrawStep && data instanceof LDrawPart)) {
event.feedback = DND.FEEDBACK_NONE;
} else {
event.feedback |= DND.FEEDBACK_SELECT;
}
}
} else {
event.detail = DND.DROP_NONE;
}
}
@Override
public void dragOperationChanged(DropTargetEvent event) {
}
@Override
public void dragLeave(DropTargetEvent event) {
}
@Override
public void dragEnter(DropTargetEvent event) {
}
});
}
private void deleteSelectedItems() {
TreeItem[] selectedItems = groupTreeComponent.getSelection();
DirectiveAction action = new DirectiveAction();
LDrawDirective directive;
for (TreeItem item : selectedItems) {
directive = (LDrawDirective) item.getData();
action.removeDirective(directive);
if (directive instanceof LDrawStep) {
mocBuilder.removeDirectiveFromWorkingFile(directive, true);
}
}
LDrawUndoRedoManager.getInstance().pushUndoAction(action);
mocBuilder.removeSelectedDirective();
GlobalFocusManager.getInstance().forceFocusToMainView();
}
private void setSelection() {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
if (!groupTreeComponent.isDisposed()) {
ArrayList<TreeItem> list = setSelection(groupTreeComponent
.getItems());
final TreeItem[] items = new TreeItem[list.size()];
list.toArray(items);
groupTreeComponent.setSelection(items);
}
}
});
}
private ArrayList<TreeItem> setSelection(TreeItem[] parentItems) {
ArrayList<TreeItem> selectedItems = new ArrayList<TreeItem>();
ArrayList<LDrawPart> selected = BrickSelectionManager.getInstance()
.getSelectedPartList();
LDrawDirective directive;
for (TreeItem item : parentItems) {
directive = (LDrawDirective) item.getData();
if (directive == null)
continue;
else if (directive instanceof LDrawStep) {
selectedItems.addAll(setSelection(item.getItems()));
} else if (directive instanceof LDrawDirective
&& selected.contains(directive)) {
selectedItems.add(item);
}
}
return selectedItems;
}
private void renameStep() {
for (final TreeItem item : groupTreeComponent.getSelection()) {
if (item.getData() instanceof LDrawStep) {
final Text newEditor = new Text(groupTreeComponent, SWT.NONE);
newEditor.setText(item.getText());
newEditor.addListener(SWT.FocusOut, this);
newEditor.addListener(SWT.KeyUp, this);
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item);
}
}
}
@Override
public void run() {
long lastRedrawTreeTime = System.currentTimeMillis();
HashMap<LDrawStep, Boolean> alreadyUpdated = new HashMap<LDrawStep, Boolean>();
boolean allUpdated = false;
while (isTerminate == false) {
alreadyUpdated.clear();
allUpdated = false;
if (flags.get(NotificationMessageT.LDrawPartSelected)) {
setSelection();
flags.put(NotificationMessageT.LDrawPartSelected, false);
}
if (flags.get(NotificationMessageT.LDrawFileActiveModelDidChanged)) {
if (allUpdated == false) {
initTree();
allUpdated = true;
}
flags.put(NotificationMessageT.LDrawFileActiveModelDidChanged,
false);
}
if (System.currentTimeMillis() - lastRedrawTreeTime > 100) {
if (flags.get(NotificationMessageT.LDrawPartAdded)) {
if (allUpdated == false)
for (INotificationMessage msg : getMessageList(NotificationMessageT.LDrawPartAdded)) {
LDrawStep step = (LDrawStep) ((LDrawDirectiveAdded) msg)
.getParent();
if (alreadyUpdated.get(step) == null) {
updateStep(step);
alreadyUpdated.put(step, true);
}
}
messageListMap.get(NotificationMessageT.LDrawPartAdded)
.clear();
flags.put(NotificationMessageT.LDrawPartAdded, false);
}
if (flags.get(NotificationMessageT.LDrawPartRemoved)) {
if (allUpdated == false)
for (INotificationMessage msg : getMessageList(NotificationMessageT.LDrawPartRemoved)) {
LDrawStep step = (LDrawStep) ((LDrawDirectiveRemoved) msg)
.getParent();
if (alreadyUpdated.get(step) == null) {
updateStep(step);
alreadyUpdated.put(step, true);
}
}
messageListMap.get(NotificationMessageT.LDrawPartRemoved)
.clear();
flags.put(NotificationMessageT.LDrawPartRemoved, false);
}
if (flags.get(NotificationMessageT.LDrawDirectiveDidChange)) {
if (allUpdated == false)
for (INotificationMessage msg : getMessageList(NotificationMessageT.LDrawDirectiveDidChange)) {
LDrawStep step = (LDrawStep) ((LDrawDirectiveModified) msg)
.getParent();
if (alreadyUpdated.get(step) == null) {
updateStep(step);
alreadyUpdated.put(step, true);
}
}
messageListMap.get(
NotificationMessageT.LDrawDirectiveDidChange)
.clear();
flags.put(NotificationMessageT.LDrawPartRemoved, false);
}
if (flags.get(NotificationMessageT.LDrawStepAdded)) {
if (allUpdated == false) {
initTree();
allUpdated = true;
}
messageListMap.get(NotificationMessageT.LDrawStepAdded)
.clear();
flags.put(NotificationMessageT.LDrawStepAdded, false);
}
if (flags.get(NotificationMessageT.LDrawStepRemoved)) {
if (allUpdated == false) {
initTree();
allUpdated = true;
}
messageListMap.get(NotificationMessageT.LDrawStepRemoved)
.clear();
flags.put(NotificationMessageT.LDrawStepRemoved, false);
}
if (flags.get(NotificationMessageT.LDrawPartTransformed)) {
if (allUpdated == false)
for (INotificationMessage msg : getMessageList(NotificationMessageT.LDrawPartTransformed)) {
LDrawStep step = (LDrawStep) ((LDrawDirectiveModified) msg)
.getParent();
if (alreadyUpdated.get(step) != null) {
updateStep(step);
alreadyUpdated.put(step, true);
}
}
messageListMap.get(
NotificationMessageT.LDrawPartTransformed).clear();
flags.put(NotificationMessageT.LDrawPartTransformed, false);
}
lastRedrawTreeTime = System.currentTimeMillis();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void handleEvent(Event event) {
Text text = (Text) editor.getEditor();
if (event.keyCode == 0 || event.keyCode == SWT.CR) {
String name = text.getText();
TreeItem item = editor.getItem();
LDrawStep step = (LDrawStep) item.getData();
step.setStepName(name);
if ("".equals(name)) {
name = "Step "
+ (step.enclosingDirective().indexOfDirective(step) + 1);
}
item.setText(name);
text.dispose();
} else if (event.keyCode == SWT.ESC) {
text.dispose();
}
}
}